<style>
:root {--hue: 120;--bg: hsl(var(--hue),10%,90%);--fg: hsl(var(--hue),10%,10%);--primary: hsl(var(--hue),90%,55%);--shadow: hsl(var(--hue),90%,35%);font-size: calc(20px + (40 - 20) * (100vw - 320px) / (1280 - 320));}
.clock {background-color: var(--primary);background-image: linear-gradient(-45deg,hsla(var(--hue),10%,10%,0),hsla(var(--hue),10%,10%,0.2));border-radius: 0.25rem;box-shadow: 0 0 0 0.1rem hsla(var(--hue),10%,10%,0.2) inset;color: hsl(var(--hue),10%,100%);display: flex;justify-content: center;font-size: 2em;line-height: 1;padding: 0.25rem 0.5rem;}
.clock__digit {display: inline-block;font-weight: bold;text-align: center;text-shadow:0 0 0 var(--shadow),0 0 0 var(--shadow),1px 1px 0 var(--shadow),2px 2px 0 var(--shadow),3px 3px 0 var(--shadow),3px 3px 0 var(--shadow),4px 4px 0 var(--shadow);width: 1ch;}
.clock__digit:not(:nth-child(3n)) {margin-top: 0.25rem;}
.clock__digit--bounce {animation: bounce 0.5s ease-in;}
/* Dark theme */
@media (prefers-color-scheme: dark) {:root {--bg: hsl(var(--hue),10%,10%);--fg: hsl(var(--hue),10%,90%);}}
/* Animations */
@keyframes bounce {from, to {animation-timing-function: ease-in;text-shadow:0 0 0 var(--shadow),0 0 0 var(--shadow),1px 1px 0 var(--shadow),2px 2px 0 var(--shadow),3px 3px 0 var(--shadow),3px 3px 0 var(--shadow),4px 4px 0 var(--shadow);transform: translate(0,0);}33% {animation-timing-function: ease-out;text-shadow:0 0 0 var(--shadow),0 0 0 var(--shadow),0 0 0 var(--shadow),0 0 0 var(--shadow),0 0 0 var(--shadow),1px 1px 0 var(--shadow);transform: translate(4px,4px);}67% {animation-timing-function: ease-in;text-shadow:1px 1px 0 var(--shadow),2px 2px 0 var(--shadow),3px 3px 0 var(--shadow),4px 4px 0 var(--shadow),5px 5px 0 var(--shadow),6px 6px 0 var(--shadow);transform: translate(-2px,-2px);}}
</style>
<div style="display: grid;place-items: center;">
<div class="clock">
<span class="clock__digit">0</span>
<span class="clock__digit">0</span>
<span class="clock__digit">:</span>
<span class="clock__digit">0</span>
<span class="clock__digit">0</span>
<span class="clock__digit">:</span>
<span class="clock__digit">0</span>
<span class="clock__digit">0</span>
</div>
</div>
<script>
window.addEventListener("DOMContentLoaded",() => {
	const clock = new BouncyEmbossedClock(".clock");
});
class BouncyEmbossedClock {
	constructor(el) {
		this.el = document.querySelector(el);
		this.els = this.el ? this.el.querySelectorAll(".clock__digit") : [];
		this.digits = [];
		this.to = null;
		this.dto = [
			[null,null,null],
			[null,null,null],
			[null,null],
			[null,null,null],
			[null,null,null],
			[null,null],
			[null,null,null],
			[null,null,null],
		];
		this.staticUpdate();
		this.update();
	}
	getTime() {
		const time = new Date();
		const hms = [
			time.getHours(),
			time.getMinutes(),
			time.getSeconds()
		];
		return hms.map(u => u < 10 ? `0${u}` : `${u}`).join(":").split("");	
	}
	staticUpdate() {
		if (this.els) {
			this.digits = this.getTime();
			this.digits.forEach((d,i) => {
				this.els[i].textContent = d;
			});
		}
	}
	update() {
		if (this.els) {
			// get the time
			const display = this.getTime();
			const bounce = "clock__digit--bounce";
			const baseDelay = 350;
			const delayDec = 50;
			// display the digits
			display.forEach((d,i) => {
				if (+d > +this.digits[i] || +d === 0 && +this.digits[i] !== 0) {
					const colonElCL = display[i + 1] === ":" ? this.els[i + 1].classList : null;
					const el = this.els[i];
					const timeout = baseDelay - delayDec * i;
					this.dto[i].forEach(t => {
						clearTimeout(t);
					});
					// run the animation
					this.dto[i][0] = setTimeout(() => {
						el.classList.add(bounce);
					}, timeout);
					// show the next digit
					this.dto[i][1] = setTimeout(() => {
						el.textContent = d;
					}, timeout + 167);
					// kill the animation
					this.dto[i][2] = setTimeout(() => {
						el.classList.remove(bounce);
					}, timeout + 500);
					// colon animation (if applicable)
					if (colonElCL) {
						this.dto[i + 1].forEach(t => {
							clearTimeout(t);
						});
						this.dto[i + 1][0] = setTimeout(() => {
							 colonElCL.add(bounce);
						}, timeout - delayDec);
						this.dto[i + 1][1] = setTimeout(() => {
							 colonElCL.remove(bounce);
						}, (timeout - delayDec) + 500);
					}
				}
				this.digits[i] = d;
			});
			// loop
			clearTimeout(this.to);
			this.to = setTimeout(this.update.bind(this),1e3);
		}
	}
}
</script>